package com.freeheart.validation.constraints;

import com.freeheart.validation.constraintvalidators.recent.CompositionRecentConstraintValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * 对日期、时间进行是否满足最近几个时间单位进行属性校验注解。
 * 支持校验过去近几天、也支持校验未来近几天。
 */
@Target({FIELD, PARAMETER,TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {
        CompositionRecentConstraintValidator.class
})
public @interface Recent {
    /**
     * 最近多少 时间单位？
     * 最近两天的定义是：今天和昨天。
     * 值为1DAYS代表只能是今天。
     * 最近两小时指的是：现在小时数和上一个小数数。以此类推...
     * <p>
     * 注意：如果小于1，将不做校验。可以理解为，以当前时刻为圆心，value为半径，向过去和未来（如果containFuture设置为true）展开区间。
     * 在区间内部的时刻代表合法，不在区间内，视为不合法，校验不通过。
     *
     * @return 数值
     */
    long value() default 1;

    /**
     * 时间单位
     *
     * @return 默认是天
     */
    TimeUnit timeUnit() default TimeUnit.DAYS;

    /**
     * 计算时间差时是日期、时间是否被截断。
     * 例如：以 `2025-04-29 22:52:30.465`为例。
     * 如果timeUnit为DAYS，截断以后为：2025-04-29 (00:00:00.000)。
     * 如果timeUnit为HOURS，截断以后为：2025-04-29 22:00:00.000
     * 如果timeUnit为MINUTES，截断以后为：2025-04-29 22:52:00.000
     * 如果timeUnit为SECONDS，截断以后为：2025-04-29 22:52:30.000
     *
     * @return 是否截断后计算
     */
    boolean truncate() default true;

    /**
     * 最近一般指的是过去到现在的时间范围，如果该参数设置为true，表示还包括现在到未来的时间范围。
     * 实际检验效果为：判断日期、时间是否在[-value,value]的双开闭区间内。
     * 例如：
     *
     * @return 是否包括未来的时间范围
     */
    boolean containFuture() default false;

    /**
     * 如果要校验的是 具有日期格式的字符串，需要提供日期格式，
     * 代码会将其解析为：LocalDate、LocalDateTime来进行计算。
     *
     * @return 日期、时间格式的字符串
     */
    String formater() default "yyyy-MM-dd";

    /**
     * 校验失败以后的错误描述信息。支持变量引用。
     * {value} 会被替换为value值
     * {timeUnit} 会被转化为：天、时、分、秒、毫秒、微秒、纳秒
     *
     * @return 错误描述信息
     */
    String message() default "不在最近{value}{timeUnit}内";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};


}
